
/**    // this.tip;
 * @class MeasureTools
 * @description 测量工具集合
 * @version 1.0
 * @author Hejiang <@link 2268027569@qq.com|邮箱>
 * @copyright Hejiang 修改时间: 2024-1-19
 */
class MeasureTools {
  constructor(viewer) {
    this._viewer = viewer;
    this.measureLayer = new Cesium.CustomDataSource("测量图层");
    this._viewer.dataSources.add(this.measureLayer);
    this.resultLayer = new Cesium.CustomDataSource("测量结果图层");
    this._viewer.dataSources.add(this.resultLayer);
    this.handler = new Cesium.ScreenSpaceEventHandler(
      this._viewer.scene.canvas
    );
    // this.tip;
    this.tempLine;
    this.goOnArea = true;
    this.goOnAngle = true;
  }
  /**
   * @method measureSpaceDistance 空间距离测量
   */
  measureSpaceDistance() {
    let pointArr = [];
    this.handler.setInputAction((e) => {
      let cartesian = this._viewer.scene.pickPosition(e.position);

      if (Cesium.defined(cartesian)) {
        pointArr.push(cartesian);
        let point = new Cesium.Entity({
          position: cartesian,
          point: {
            pixelSize: 7,
            color: Cesium.Color.YELLOW,
            outlineColor: Cesium.Color.BLUE,
            outlineWidth: 2,
          },
        });
        this.measureLayer.entities.add(point);
        if (pointArr.length > 1) {
          let line = new Cesium.Entity({
            polyline: {
              positions: pointArr.slice(pointArr.length - 2),
              material: Cesium.Color.ORANGE,
              width: 3,
            },
          });
          this.measureLayer.entities.add(line);
          let distance = 0;
          for (let index = 0; index <= pointArr.length - 2; index++) {
            distance += Cesium.Cartesian3.distance(
              pointArr[index],
              pointArr[index + 1]
            );
          }
          distance = `${(distance / 1000).toFixed(3)}公里`;
          let originPosition = pointArr[pointArr.length - 1];
          let originCartographic =
            Cesium.Cartographic.fromCartesian(originPosition);

          let label = new Cesium.Entity({
            position: Cesium.Cartesian3.fromRadians(
              originCartographic.longitude,
              originCartographic.latitude,
              originCartographic.height + 20
            ),
            label: {
              text: distance,
              font: "bold 20px KaiTi",
              fillColor: Cesium.Color.ORANGE,
              backgroundColor: Cesium.Color.BLACK.withAlpha(0.5),
              showBackground: true,
              pixelOffset: new Cesium.Cartesian2(0, -40),
              outerWidth: 2,
              outlineColor: Cesium.Color.AQUA,
              scaleByDistance: new Cesium.NearFarScalar(1, 1.5, 300000, 0.3),
              heightReference: Cesium.HeightReference.NONE,
            },
          });
          this.measureLayer.entities.add(label);
        }
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    this.handler.setInputAction((e) => {
      if (pointArr.length >= 1) {
        let cartesianMove = this._viewer.scene.pickPosition(e.endPosition);
        if (Cesium.defined(cartesianMove)) {
          if (Cesium.defined(this.tempLine)) {
            this._viewer.entities.remove(this.tempLine);
          }
          this.tempLine = new Cesium.Entity({
            polyline: {
              positions: new Cesium.CallbackProperty(() => {
                return [pointArr[pointArr.length - 1], cartesianMove];
              }, false),
              material: Cesium.Color.ORANGE,
              width: 3,
            },
          });

          this._viewer.entities.add(this.tempLine);
        }
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    this.handler.setInputAction((e) => {
      if (Cesium.defined(this.tempLine)) {
        this._viewer.entities.remove(this.tempLine);
      }
      this.removeEvent();
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  }

  /**
   * @method measureSurfaceDistance 地表距离测量
   */
  measureSurfaceDistance() {
    let pointArr = [];
    let tempLine;
    this.handler.setInputAction((e) => {
      let cartesian = this._viewer.scene.pickPosition(e.position);
      if (Cesium.defined(cartesian)) {
        let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
        cartesian = Cesium.Cartesian3.fromRadians(
          cartographic.longitude,
          cartographic.latitude,
          cartographic.height + 0.01
        );
        pointArr.push(cartesian);
        let point = new Cesium.Entity({
          position: cartesian,
          point: {
            pixelSize: 7,
            color: Cesium.Color.YELLOW,
            outlineColor: Cesium.Color.BLUE,
            outlineWidth: 2,
          },
        });

        this.measureLayer.entities.add(point);
        if (pointArr.length > 1) {
          let line = new Cesium.Entity({
            polyline: {
              positions: pointArr.slice(pointArr.length - 2),
              material: Cesium.Color.AQUA,
              width: 3,
              clampToGround: true,
            },
          });
          this.measureLayer.entities.add(line);
        }
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    this.handler.setInputAction((e) => {
      if (pointArr.length >= 1) {
        let cartesianMove = this._viewer.scene.pickPosition(e.endPosition);
        let cartographic = Cesium.Cartographic.fromCartesian(cartesianMove);
        cartesianMove = Cesium.Cartesian3.fromRadians(
          cartographic.longitude,
          cartographic.latitude,
          cartographic.height + 0.01
        );
        if (Cesium.defined(cartesianMove)) {
          if (Cesium.defined(this.tempLine)) {
            this._viewer.entities.remove(this.tempLine);
          }
          this.tempLine = new Cesium.Entity({
            polyline: {
              positions: new Cesium.CallbackProperty(() => {
                return [pointArr[pointArr.length - 1], cartesianMove];
              }, false),
              material: Cesium.Color.YELLOW,
              width: 3,
              clampToGround: true,
            },
          });

          this._viewer.entities.add(this.tempLine);
        }
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    this.handler.setInputAction((e) => {
      if (this.tempLine) {
        this._viewer.entities.remove(this.tempLine);
      }
      let promise = new Promise((resolve, reject) => {
        if (pointArr.length > 1) {
          for (let j = 0; j <= pointArr.length - 2; j++) {
            let start = pointArr[j];
            let end = pointArr[j + 1];
            let tempDistance = Cesium.Cartesian3.distance(start, end);
            let length = Math.round(tempDistance) / 1000;
            //根据量测的尺度进行插值分度值的设置
            let lerpPointCount;
            if (length > 100) {
              //大于100公里，每隔一米插一个点
              lerpPointCount = length * 100;
            } else if (length > 50) {
              //50公里-100公里，每隔0.5米插一个点
              lerpPointCount = length * 100;
            } else if (length > 10) {
              //10-50公里,每隔0.2米插一个点
              lerpPointCount = length * 100;
            } else if (length > 5) {
              lerpPointCount = length * 1000;
              //5-10 公里， 每隔10厘米 插一个点
            } else if (length > 1) {
              //1-5gongli ，每隔1厘米插入一个点
              lerpPointCount = length * 1000;
            } else {
              //一公里以内，每隔2毫米差一个点
              lerpPointCount = length * 1000;
            }
            let lerpArr = [];

            for (let i = 1; i <= lerpPointCount; i++) {
              var cart = new Cesium.Cartesian3();
              Cesium.Cartesian3.lerp(start, end, i / lerpPointCount, cart);
              lerpArr.push(cart);
            }
            lerpArr.slice(0, 0, start);
            lerpArr.push(end);
            let distance = 0;
            let lerpResultArr = [];
            //对3d瓦片采样
            this._viewer.scene
              .clampToHeightMostDetailed(lerpArr)
              .then((result) => {
                result.filter((e) => {
                  return e.z !== undefined;
                });
                result.forEach((li) => {
                  lerpResultArr.push(li);
                  if (Cesium.defined(li)) {
                    li = Cesium.Cartographic.fromCartesian(li);

                    let point = new Cesium.Entity({
                      position: Cesium.Cartesian3.fromRadians(
                        li.longitude,
                        li.latitude,
                        li.height + 0.1
                      ),
                      point: {
                        pixelSize: 2,
                        color: Cesium.Color.RED,
                      },
                    });
                    this.measureLayer.entities.add(point);
                  }
                });

                for (
                  let index = 0;
                  index <= lerpResultArr.length - 2;
                  index++
                ) {
                  distance += Cesium.Cartesian3.distance(
                    lerpResultArr[index],
                    lerpResultArr[index + 1]
                  );
                }
                distance = `${(distance / 1000).toFixed(3)}公里`;
                let label = new Cesium.Entity({
                  position: pointArr[j + 1],
                  label: {
                    text: distance,
                    font: "bold 20px KaiTi",
                    fillColor: Cesium.Color.ORANGE,
                    backgroundColor: Cesium.Color.BLACK.withAlpha(0.5),
                    showBackground: true,
                    pixelOffset: new Cesium.Cartesian2(0, -40),
                    outerWidth: 2,
                    outlineColor: Cesium.Color.AQUA,
                    scaleByDistance: new Cesium.NearFarScalar(
                      1,
                      1.5,
                      300000,
                      0.3
                    ),
                    heightReference: Cesium.HeightReference.NONE,
                  },
                });
                this.measureLayer.entities.add(label);
              });
          }
          resolve();
        }
      });
      promise.then((res) => {
        let cartesianRightClick = this._viewer.scene.pickPosition(e.position);
        if (Cesium.defined(cartesianRightClick)) {
          this._viewer.entities.remove(this.tempLine);
          // this.tip.close();
          this.removeEvent();
        }
      });
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  }

  /**
   * @method measureSurfaceDistance2 地表距离测量 --（大圆测地线插值+地表采样）
   */
  measureSurfaceDistance2() {
    let pointArr = [];
    let tempLine;
    this.handler.setInputAction((e) => {
      let cartesian = this._viewer.scene.pickPosition(e.position);
      if (Cesium.defined(cartesian)) {
        let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
        cartesian = Cesium.Cartesian3.fromRadians(
          cartographic.longitude,
          cartographic.latitude,
          cartographic.height + 0.01
        );
        pointArr.push(cartesian);
        let point = new Cesium.Entity({
          position: cartesian,
          point: {
            pixelSize: 7,
            color: Cesium.Color.YELLOW,
            outlineColor: Cesium.Color.BLUE,
            outlineWidth: 2,
          },
        });

        this.measureLayer.entities.add(point);
        if (pointArr.length > 1) {
          let line = new Cesium.Entity({
            polyline: {
              positions: pointArr.slice(pointArr.length - 2),
              material: Cesium.Color.AQUA,
              width: 3,
              clampToGround: true,
            },
          });
          this.measureLayer.entities.add(line);
        }
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    this.handler.setInputAction((e) => {
      if (pointArr.length >= 1) {
        let cartesianMove = this._viewer.scene.pickPosition(e.endPosition);
        let cartographic = Cesium.Cartographic.fromCartesian(cartesianMove);
        cartesianMove = Cesium.Cartesian3.fromRadians(
          cartographic.longitude,
          cartographic.latitude,
          cartographic.height + 0.01
        );
        if (Cesium.defined(cartesianMove)) {
          if (Cesium.defined(this.tempLine)) {
            this._viewer.entities.remove(this.tempLine);
          }
          this.tempLine = new Cesium.Entity({
            polyline: {
              positions: new Cesium.CallbackProperty(() => {
                return [pointArr[pointArr.length - 1], cartesianMove];
              }, false),
              material: Cesium.Color.AQUA,
              width: 3,
              clampToGround: true,
            },
          });

          this._viewer.entities.add(this.tempLine);
        }
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    this.handler.setInputAction((e) => {
      if (this.tempLine) {
        this._viewer.entities.remove(this.tempLine);
      }
      // this.tip.close();
      let promise = new Promise((resolve, reject) => {
        if (pointArr.length > 1) {
          for (let j = 0; j <= pointArr.length - 2; j++) {
            let start = pointArr[j];
            let end = pointArr[j + 1];
            let startCartographic = Cesium.Cartographic.fromCartesian(start);
            let endCartographic = Cesium.Cartographic.fromCartesian(end);
            //创建大圆测地线
            var geodesic = new Cesium.EllipsoidGeodesic(); //创建大圆测地线
            geodesic.setEndPoints(startCartographic, endCartographic); // 设置测地线的起点和终点
            let tempDistance = Cesium.Cartesian3.distance(start, end);
            var lerpPts = [startCartographic];
            for (let i = 0; i < tempDistance; i++) {
              //分段采样计算距离
              var cartoPt = geodesic.interpolateUsingSurfaceDistance(i);
              lerpPts.push(cartoPt);
            }
            lerpPts.push(endCartographic);

            Cesium.sampleTerrainMostDetailed(
              this._viewer.terrainProvider,
              lerpPts
            ).then((updateArray) => {
              updateArray = updateArray.map((e) => {
                return Cesium.Cartesian3.fromRadians(
                  e.longitude,
                  e.latitude,
                  e.height
                );
              });
              let distanceSum = 0;
              for (let i = 0; i < updateArray.length - 1; i++) {
                distanceSum += Cesium.Cartesian3.distance(
                  updateArray[i],
                  updateArray[i + 1]
                );
              }
              let label = new Cesium.Entity({
                position: pointArr[j + 1],
                label: {
                  text: (distanceSum / 1000).toFixed(3) + "公里",
                  font: "bold 20px KaiTi",
                  fillColor: Cesium.Color.AQUA,
                  backgroundColor: Cesium.Color.BLACK.withAlpha(0.5),
                  showBackground: true,
                  pixelOffset: new Cesium.Cartesian2(0, -40),
                  outerWidth: 2,
                  outlineColor: Cesium.Color.ORANGE,
                  scaleByDistance: new Cesium.NearFarScalar(
                    1,
                    1.5,
                    300000,
                    0.3
                  ),
                  heightReference: Cesium.HeightReference.NONE,
                },
              });
              this.measureLayer.entities.add(label);
            });
          }
          resolve();
        }
      });
      promise.then((res) => {
        let cartesianRightClick = this._viewer.scene.pickPosition(e.position);
        if (Cesium.defined(cartesianRightClick)) {
          this._viewer.entities.remove(this.tempLine);
          // this.tip.close();
          this.removeEvent();
        }
      });
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  }

  /**
   * @method measureTriangulation 三角测量
   */
  measureTriangulation() {
    //执行地形检查
    let flag = this.checkTerrain();
    if (!flag) {
      ElMessage({
        type: "error",
        message: "未提供地形数据，无法测量！",
        duration: 3000,
        offset: 90,
      });
      return;
    }

    let pointArr = [];
    let line1;
    let line2;
    let line3;
    let text1, text2, text3;
    let startDeglabel, endDegLabel;
    this.removeEvent();
    if (this.tempLine) {
      this._viewer.entities.remove(this.tempLine);
    }
    //左键加点事件

    this.handler.setInputAction((e) => {
      let cartesian = this._viewer.scene.pickPosition(e.position);
      console.log(Cesium.defined(cartesian), "Cesium.defined(cartesian)");
      if (Cesium.defined(cartesian)) {
        if (pointArr.length < 1) {
          let point = new Cesium.Entity({
            position: cartesian,
            point: {
              pixelSize: 5,
              fillColor: Cesium.Color.YELLOW,
              outlineWidth: 2,
              outlineColor: Cesium.Color.AQUA,
              heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
            },
          });
          pointArr.push(cartesian);
          this.measureLayer.entities.add(point);
        }
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    //鼠标移动事件
    this.handler.setInputAction((evt) => {
      if (pointArr.length == 1) {
        let cartesianMove = this._viewer.scene.pickPosition(evt.endPosition);
        if (Cesium.defined(cartesianMove)) {
          if (line1) {
            this.measureLayer.entities.remove(line1);
          }
          if (line2) {
            this.measureLayer.entities.remove(line2);
          }
          if (line3) {
            this.measureLayer.entities.remove(line3);
          }
          if (text1) {
            this.measureLayer.entities.remove(text1);
          }
          if (text2) {
            this.measureLayer.entities.remove(text2);
          }
          if (text3) {
            this.measureLayer.entities.remove(text3);
          }
          let res = this.getAngleCartesian(pointArr[0], cartesianMove);

          let line1Mid = Cesium.Cartesian3.midpoint(
            pointArr[0],
            cartesianMove,
            new Cesium.Cartesian3()
          );
          let line2Mid = Cesium.Cartesian3.midpoint(
            pointArr[0],
            Cesium.Cartesian3.fromRadians(
              res[1].longitude,
              res[1].latitude,
              res[1].height
            ),
            new Cesium.Cartesian3()
          );
          let line3Mid = Cesium.Cartesian3.midpoint(
            cartesianMove,
            Cesium.Cartesian3.fromRadians(
              res[1].longitude,
              res[1].latitude,
              res[1].height
            ),
            new Cesium.Cartesian3()
          );
          let label1 = this.formatLength(
            Cesium.Cartesian3.distance(pointArr[0], cartesianMove)
          );
          let label21 = this.formatLength(
            Cesium.Cartesian3.distance(
              pointArr[0],
              Cesium.Cartesian3.fromRadians(
                res[1].longitude,
                res[1].latitude,
                res[1].height
              )
            )
          );
          let label22 = this.formatLength(
            Cesium.Cartesian3.distance(
              cartesianMove,
              Cesium.Cartesian3.fromRadians(
                res[1].longitude,
                res[1].latitude,
                res[1].height
              )
            )
          );

          let label31 = this.formatLength(
            Math.abs(
              Cesium.Cartographic.fromCartesian(cartesianMove).height -
                res[1].height
            )
          );

          let label32 = this.formatLength(
            Math.abs(
              Cesium.Cartographic.fromCartesian(pointArr[0]).height -
                res[1].height
            )
          );

          line1 = new Cesium.Entity({
            polyline: {
              positions: new Cesium.CallbackProperty(() => {
                return [pointArr[0], cartesianMove];
              }, false),
              width: 3,
              material: Cesium.Color.YELLOW,
            },
          });
          text1 = new Cesium.Entity({
            position: line1Mid,
            label: {
              text: new Cesium.CallbackProperty(() => {
                return label1;
              }, false),
              fillColor: Cesium.Color.WHITE,
              font: "bold 18px KaiTi",
              // pixelOffset: new Cesium.Cartesian2(-30, 0),
              disableDepthTestDistance: 100000,
              scaleByDistance: new Cesium.NearFarScalar(1, 1.5, 300000, 0.3),
              heightReference: Cesium.HeightReference.NONE,
            },
          });
          this.measureLayer.entities.add(line1);
          this.measureLayer.entities.add(text1);

          line2 = new Cesium.Entity({
            polyline: {
              positions: new Cesium.CallbackProperty(() => {
                return [
                  pointArr[0],
                  Cesium.Cartesian3.fromRadians(
                    res[1].longitude,
                    res[1].latitude,
                    res[1].height
                  ),
                ];
              }, false),
              width: 3,
              material: Cesium.Color.YELLOW,
            },
          });
          text2 = new Cesium.Entity({
            position: line2Mid,
            label: {
              text: new Cesium.CallbackProperty(() => {
                if (
                  Cesium.Cartographic.fromCartesian(cartesianMove).height <=
                  res[0].height
                ) {
                  return label21;
                } else {
                  return label32;
                }
              }, false),
              fillColor: Cesium.Color.WHITE,
              font: "bold 18px KaiTi",
              disableDepthTestDistance: 100000,
              scaleByDistance: new Cesium.NearFarScalar(1, 1.5, 300000, 0.3),
              heightReference: Cesium.HeightReference.NONE,
            },
          });
          this.measureLayer.entities.add(text2);
          this.measureLayer.entities.add(line2);
          line3 = new Cesium.Entity({
            polyline: {
              positions: new Cesium.CallbackProperty(() => {
                return [
                  cartesianMove,
                  Cesium.Cartesian3.fromRadians(
                    res[1].longitude,
                    res[1].latitude,
                    res[1].height
                  ),
                ];
              }, false),
              width: 3,
              material: Cesium.Color.YELLOW,
            },
          });
          text3 = new Cesium.Entity({
            position: line3Mid,
            label: {
              text: new Cesium.CallbackProperty(() => {
                if (
                  Cesium.Cartographic.fromCartesian(cartesianMove).height >=
                  res[0].height
                ) {
                  return label22;
                } else {
                  return label31;
                }
              }, false),
              fillColor: Cesium.Color.WHITE,
              font: "bold 18px KaiTi",
              // pixelOffset: new Cesium.Cartesian2(-30, 0),
              disableDepthTestDistance: 100000,
              scaleByDistance: new Cesium.NearFarScalar(1, 1.5, 300000, 0.3),
              heightReference: Cesium.HeightReference.NONE,
            },
          });
          this.measureLayer.entities.add(line3);
          this.measureLayer.entities.add(text3);

          //计算两个线的方向向量
          let dircetion1 = Cesium.Cartesian3.subtract(
            pointArr[0],
            cartesianMove,
            new Cesium.Cartesian3()
          );
          let dircetion2 = Cesium.Cartesian3.subtract(
            pointArr[0],
            Cesium.Cartesian3.fromRadians(
              res[1].longitude,
              res[1].latitude,
              res[1].height
            ),
            new Cesium.Cartesian3()
          );
          // 归一化向量
          Cesium.Cartesian3.normalize(dircetion1, dircetion1);
          Cesium.Cartesian3.normalize(dircetion2, dircetion2);
          let deg = Cesium.Cartesian3.angleBetween(dircetion1, dircetion2);
          let startDeg = Cesium.Math.toDegrees(deg).toFixed(2);
          let endDeg = (90 - startDeg).toFixed(2);
          if (startDeglabel) {
            this.measureLayer.entities.remove(startDeglabel);
          }
          if (endDegLabel) {
            this.measureLayer.entities.remove(endDegLabel);
          }
          //标注角度
          startDeglabel = new Cesium.Entity({
            position: new Cesium.CallbackProperty(() => {
              return pointArr[0];
            }, false),
            label: {
              text: `${startDeg}°`,
              font: " 18px KaiTi",
              fillColor: Cesium.Color.fromCssColorString("#d83317"),
              horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
              disableDepthTestDistance: 100000,
              scaleByDistance: new Cesium.NearFarScalar(1, 1.5, 300000, 0.3),
              heightReference: Cesium.HeightReference.NONE,
            },
          });
          endDegLabel = new Cesium.Entity({
            position: new Cesium.CallbackProperty(() => {
              return cartesianMove;
            }, false),
            label: {
              text: `${endDeg}°`,
              font: " 18px KaiTi",
              fillColor: Cesium.Color.fromCssColorString("#d83317"),
              horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
              disableDepthTestDistance: 100000,
              scaleByDistance: new Cesium.NearFarScalar(1, 1.5, 300000, 0.3),
              heightReference: Cesium.HeightReference.NONE,
            },
          });
          this.measureLayer.entities.add(startDeglabel);
          this.measureLayer.entities.add(endDegLabel);
        }
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    //右键结束绘制
    this.handler.setInputAction((e) => {
      this.removeEvent();
      if (this.goOnAngle) {
        this.measureTriangulation();
      }
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  }

  /**
   * @method formatLength 格式化长度
   */
  formatLength(number) {
    if (number > 1000) {
      let result = (number / Math.pow(10, 3)).toFixed(3);
      let result2 = this.formatNumberSplit(result) + "公里";
      return result2;
    } else {
      let result = number.toFixed(3);
      let result2 = this.formatNumberSplit(result) + "米";
      return result2;
    }
  }

  /**
   * @method changeMeasureArea 改变面积测量
   */
  changeMeasureArea() {
    this.goOnArea = true;
    this.measureArea();
  }

  /**
   * @method changeMeasureAngle 改变三角测量
   */
  changeMeasureAngle() {
    this.goOnAngle = true;
    this.measureTriangulation();
  }

  /**
   * @method measureArea 面积测量
   */
  measureArea() {
    let flag = this.checkTerrain();
    if (!flag) {
      ElMessage({
        type: "error",
        message: "未提供地形数据，无法测量！",
        duration: 3000,
        offset: 90,
      });
      return;
    }

    let pointArr = [];
    let tempPolygon;
    let tempLine;
    // if (this.tip) {
    //   // this.tip.close();
    // }
    this.removeEvent();

    //左击加点事件
    this.handler.setInputAction((e) => {
      let cartesian = this._viewer.scene.pickPosition(e.position);
      if (Cesium.defined(cartesian)) {
        let point = new Cesium.Entity({
          position: cartesian,
          point: {
            pixelSize: 5,
            outlineWidth: 2,
            outlineColor: Cesium.Color.AQUA,
            fillColor: Cesium.Color.YELLOW,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
          },
        });
        this.measureLayer.entities.add(point);
        pointArr.push(cartesian);
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

    //鼠标移动的动态面事件
    this.handler.setInputAction((evt) => {
      let cartesianMove = this._viewer.scene.pickPosition(evt.endPosition);
      if (Cesium.defined(cartesianMove)) {
        if (pointArr.length == 1) {
          if (tempLine) {
            this.measureLayer.entities.remove(tempLine);
          }

          tempLine = new Cesium.Entity({
            polyline: {
              positions: new Cesium.CallbackProperty(() => {
                return pointArr.concat([cartesianMove]);
              }, false),
              width: 5,
              material: Cesium.Color.YELLOW,
              clampToGround: true,
            },
          });
          this.measureLayer.entities.add(tempLine);
        } else {
          this.measureLayer.entities.remove(tempLine);
        }
        if (pointArr.length >= 1) {
          let tempPolygonPositions = pointArr.concat([cartesianMove]);
          if (tempPolygon) {
            this.measureLayer.entities.remove(tempPolygon);
          }

          tempPolygon = new Cesium.Entity({
            polygon: {
              hierarchy: new Cesium.CallbackProperty(() => {
                return new Cesium.PolygonHierarchy(tempPolygonPositions);
              }, false),
              outerWidth: 3,
              outlineColor: Cesium.Color.AQUA,
              material: Cesium.Color.ORANGE.withAlpha(0.5),
              clampToGround: true,
            },
          });
          this.measureLayer.entities.add(tempPolygon);
        }
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    //鼠标右击的结束绘制事件
    this.handler.setInputAction((e) => {
      if (pointArr.length <= 2) {
        ElMessage.closeAll();
        ElMessage({
          type: "warning",
          message: "请至少提供三个点位！",
          duration: 3000,
          offset: 90,
        });
        return;
      }
      this.removeEvent();
      if (tempPolygon) {
        this.measureLayer.entities.remove(tempPolygon);
      }
      //新版思路：
      let polygon = new Cesium.Entity({
        polygon: {
          hierarchy: {
            positions: pointArr,
          },
          outerWidth: 3,
          outlineColor: Cesium.Color.AQUA,
          material: Cesium.Color.AQUA.withAlpha(0.5),
          clampToGround: true,
        },
      });
      this.resultLayer.entities.add(polygon);
      let area = this.getArea(pointArr);
      let position = pointArr[pointArr.length - 1];
      let posCarto = Cesium.Cartographic.fromCartesian(position);
      let newPosition = Cesium.Cartesian3.fromRadians(
        posCarto.longitude,
        posCarto.latitude,
        posCarto.height + 10
      );
      let label = new Cesium.Entity({
        position: newPosition,
        label: {
          text: area,
          font: "bold 18px KaiTi",
          fillColor: Cesium.Color.YELLOW,
          pixelOffset: new Cesium.Cartesian2(0, -20),
          disableDepthTestDistance: 100000,
          scaleByDistance: new Cesium.NearFarScalar(1, 1.5, 300000, 0.3),
          heightReference: Cesium.HeightReference.NONE,
        },
      });
      this.resultLayer.entities.add(label);

      // this.tip.close()
      if (this.goOnArea) {
        this.measureArea();
      }

      //旧版思路 ： 拆分+采样+分割计算
      // this._viewer.scene
      //   .clampToHeightMostDetailed(pointArr).then(result => {

      //     let polygon = new Cesium.Entity({
      //       polygon: {
      //         hierarchy: {
      //           positions: result,
      //         },
      //         outerWidth: 3,
      //         granularity: Math.PI / Math.pow(2, 11) / 64,
      //         outlineColor: Cesium.Color.AQUA,
      //         material: Cesium.Color.YELLOW.withAlpha(0.5),
      //         clampToGround: true
      //       },
      //     });
      //     let area = this.getArea(result);
      //     let label = new Cesium.Entity({
      //       position: result[result.length - 1],
      //       label: {
      //         text: area,
      //         font: "bold 18px KaiTi",
      //         fillColor: Cesium.Color.YELLOW,
      //         pixelOffset: new Cesium.Cartesian2(0, -30),
      //         heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
      //         disableDepthTestDistance:100000,
      //         scaleByDistance:new Cesium.NearFarScalar(1,1.5,100000,0.3),
      //  heightReference:Cesium.HeightReference.NONE
      //       },
      //     });
      //     this.resultLayer.entities.add(label);
      //     this.resultLayer.entities.add(polygon);
      //     // this.tip.close()
      //     if (this.goOnArea) {
      //       this.measureArea()
      //     }
      //   })
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  }

  //检查地形
  checkTerrain() {
    let flag = this._viewer.terrainProvider.availability;
    return flag;
  }

  removeEvent() {
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
    this.handler.removeInputAction(
      Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
    );
  }
  /**
   * @method measureClear 清空测量
   *
   */
  measureClear() {
    this.removeEvent();
    this.measureLayer.entities.removeAll();
    this.resultLayer.entities.removeAll();
    this.goOnArea = false;
    this.goOnAngle = false;
    if (this.tempLine) {
      this._viewer.entities.remove(this.tempLine);
    }
  }

  //从两个笛卡尔中获取三角量测的第三个点的坐标，并返回三个点的经纬弧度制坐标
  getAngleCartesian(start, end) {
    let startCartographic = Cesium.Cartographic.fromCartesian(start);
    let endCartographic = Cesium.Cartographic.fromCartesian(end);
    let center;
    if (startCartographic.height > endCartographic.height) {
      center = {
        longitude: endCartographic.longitude,
        latitude: endCartographic.latitude,
        height: startCartographic.height,
      };
    } else {
      center = {
        longitude: startCartographic.longitude,
        latitude: startCartographic.latitude,
        height: endCartographic.height,
      };
    }
    return [startCartographic, center, endCartographic];
  }

  //数字千位+ “，”
  formatNumberSplit(number) {
    // alert(number)
    // debugger

    //拿到一个数字，分割，而后将整数位的数字进行反转，数组反转，每三位插个 ",“ 逗号，而后再数组反转还原回去

    let numberArr = number.toString().split(".");

    let newArr = numberArr[0].split("");
    newArr.reverse();
    let str = "";
    if (newArr.length >= 3) {
      for (let i = 0; i <= newArr.length - 1; i++) {
        if (i != 0 && i != newArr.length - 1 && (i + 1) % 3 == 0) {
          str += newArr[i] + ",";
        } else {
          str += newArr[i];
        }
      }
      let newStr = "";
      for (let i = str.length - 1; i >= 0; i--) {
        newStr += str[i];
      }

      return newStr + "." + numberArr[1];
    } else {
      return number;
    }
  }

  //面积格式化
  formatArea(number) {
    console.log(number);
    console.log(Math.pow(10, 6));

    if (number / Math.pow(10, 6) >= 1) {
      let result = (number / Math.pow(10, 6)).toFixed(3);
      let result2 = this.formatNumberSplit(result) + "平方千米";

      return result2;
    } else {
      let result = number.toFixed(3);
      let result2 = this.formatNumberSplit(result) + "平方米";
      return result2;
    }
  }

  //计算多边形面积 -- 使用turf库
  getArea(positions) {
    // let result = 0;
    // if (positions) {
    //   let h = 0;

    //   for (let i = 1; i < positions.length; i++) {
    //     let oel = positions[i-1];
    //     let el = positions[i];
    //     h += oel.x * el.y - el.x * oel.y;
    //   }
    //   result = Math.abs(h).toFixed(2);
    // }
    // result = this.formatArea(result)
    // return result;

    let lngLatArr = [];
    positions.forEach((e) => {
      let carto = Cesium.Cartographic.fromCartesian(e);
      console.log(carto, "4444");
      let lng = Cesium.Math.toDegrees(carto.longitude);
      let lat = Cesium.Math.toDegrees(carto.latitude);
      lngLatArr.push([lng, lat]);
    });
    lngLatArr.push(lngLatArr[0]);
    let polygon = turf.polygon([lngLatArr]);
    let area = turf.area(polygon);
    let result = this.formatArea(area);
    return result;
  }
}

export default MeasureTools;
